﻿Imports SlimDX
Imports SlimDX.Direct3D9

Public Class ShaderGlass
    Implements IShader

    'Textures
    Dim Diffuse As Texture
    Dim Tint As Texture
    Dim Detail As Texture
    Dim Specular As CubeTexture
    Dim Bump As Texture
    Dim Reflection As CubeTexture

    'Scale
    Dim DiffuseScale As Single
    Dim BumpScale As Single
    Dim TintScale As Single
    Dim DetailScale As Single
    Dim SpecularScale As Single

    'Colors
    Dim PerpendicularBrightness As Single
    Dim ParallelBrightness As Single
    Dim PerpendicularColor As Color4
    Dim ParallelColor As Color4
    Dim BackgroundColor As Color4

    'Flags
    Dim ReflectionType As Short
    Dim Flags As Short

    Sub New(ByVal sglaTag As Magic.Core.Tag)
        AddHandler sglaTag.TagHasChanged, AddressOf Changed

        Dim DiffuseIndex As Integer = sglaTag("diffuse map")
        Dim TintMapIndex As Integer = sglaTag("background tint map")
        Dim ReflectionIndex As Integer = sglaTag("reflection map")
        Dim DetailIndex As Integer = sglaTag("diffuse detail map")
        Dim SpecularIndex As Integer = sglaTag("specular map")
        Dim BumpIndex As Integer = sglaTag("bump map")

        DiffuseScale = sglaTag("diffuse map scale")
        BumpScale = sglaTag("bump map scale")
        TintScale = sglaTag("background tint map scale")
        DetailScale = sglaTag("diffuse detail map scale")
        SpecularScale = sglaTag("specular map scale")

        PerpendicularBrightness = sglaTag("perpendicular brightness:[0,1]")
        ParallelBrightness = sglaTag("parallel brightness:[0,1]")
        PerpendicularColor = New SlimDX.Color4(1, sglaTag("perpendicular tint color")(0), sglaTag("perpendicular tint color")(1), sglaTag("perpendicular tint color")(2))
        ParallelColor = New SlimDX.Color4(1, sglaTag("parallel tint color")(0), sglaTag("parallel tint color")(1), sglaTag("parallel tint color")(2))
        If sglaTag("background tint color")(0) = 0 AndAlso sglaTag("background tint color")(1) = 0 AndAlso sglaTag("background tint color")(2) = 0 Then
            BackgroundColor = New SlimDX.Color4(1, 1, 1, 1)
        Else
            BackgroundColor = New SlimDX.Color4(1, sglaTag("background tint color")(0), sglaTag("background tint color")(1), sglaTag("background tint color")(2))
        End If

        ReflectionType = sglaTag("reflection type")
        Flags = sglaTag(12)

        If DiffuseIndex > -1 Then
            Diffuse = New Bitmap(magicMap.Library(DiffuseIndex)).Texture
        Else
            ' Diffuse = Globals.default2d(IShader.DefaultTextures.Additive)
        End If

        If BumpIndex > -1 Then
            Bump = New Bitmap(magicMap.Library(BumpIndex)).Texture
        Else
            'Bump = Globals.default2d(IShader.DefaultTextures.Vector)
        End If

        If TintMapIndex > -1 Then
            Tint = New Bitmap(magicMap.Library(TintMapIndex)).Texture
        Else
            ' Tint = Globals.default2d(IShader.DefaultTextures.Multiplicative)
        End If

        If DetailIndex > -1 Then
            Detail = New Bitmap(magicMap.Library(DetailIndex)).Texture
        Else
            ' Detail = Globals.default2d(IShader.DefaultTextures.SignedAdditive)
        End If

        If ReflectionIndex > -1 Then
            Reflection = New Bitmap(magicMap.Library(ReflectionIndex)).Cube
        Else
            'Reflection = Globals.defaultCube(IShader.DefaultTextures.SignedAdditive)
        End If

        If SpecularIndex > -1 Then
            Specular = New Bitmap(magicMap.Library(SpecularIndex)).Cube
        Else
            'Specular = Globals.defaultCube(IShader.DefaultTextures.Additive)
        End If
    End Sub
    Sub Changed(ByVal sglaTag As Magic.Core.Tag)
        Dim DiffuseIndex As Integer = sglaTag("diffuse map")
        Dim TintMapIndex As Integer = sglaTag("background tint map")
        Dim ReflectionIndex As Integer = sglaTag("reflection map")
        Dim DetailIndex As Integer = sglaTag("diffuse detail map")
        Dim SpecularIndex As Integer = sglaTag("specular map")
        Dim BumpIndex As Integer = sglaTag("bump map")

        DiffuseScale = sglaTag("diffuse map scale")
        BumpScale = sglaTag("bump map scale")
        TintScale = sglaTag("background tint map scale")
        DetailScale = sglaTag("diffuse detail map scale")
        SpecularScale = sglaTag("specular map scale")

        PerpendicularBrightness = sglaTag("perpendicular brightness:[0,1]")
        ParallelBrightness = sglaTag("parallel brightness:[0,1]")
        PerpendicularColor = New SlimDX.Color4(1, sglaTag("perpendicular tint color")(0), sglaTag("perpendicular tint color")(1), sglaTag("perpendicular tint color")(2))
        ParallelColor = New SlimDX.Color4(1, sglaTag("parallel tint color")(0), sglaTag("parallel tint color")(1), sglaTag("parallel tint color")(2))
        If sglaTag("background tint color")(0) = 0 AndAlso sglaTag("background tint color")(1) = 0 AndAlso sglaTag("background tint color")(2) = 0 Then
            BackgroundColor = New SlimDX.Color4(1, 1, 1, 1)
        Else
            BackgroundColor = New SlimDX.Color4(1, sglaTag("background tint color")(0), sglaTag("background tint color")(1), sglaTag("background tint color")(2))
        End If

        ReflectionType = sglaTag("reflection type")
        Flags = sglaTag(12)

        If DiffuseIndex > -1 Then
            Diffuse = New Bitmap(magicMap.Library(DiffuseIndex)).Texture
        Else
            ' Diffuse = Globals.default2d(IShader.DefaultTextures.Additive)
        End If

        If BumpIndex > -1 Then
            Bump = New Bitmap(magicMap.Library(BumpIndex)).Texture
        Else
            'Bump = Globals.default2d(IShader.DefaultTextures.Vector)
        End If

        If TintMapIndex > -1 Then
            Tint = New Bitmap(magicMap.Library(TintMapIndex)).Texture
        Else
            ' Tint = Globals.default2d(IShader.DefaultTextures.Multiplicative)
        End If

        If DetailIndex > -1 Then
            Detail = New Bitmap(magicMap.Library(DetailIndex)).Texture
        Else
            ' Detail = Globals.default2d(IShader.DefaultTextures.SignedAdditive)
        End If

        If ReflectionIndex > -1 Then
            Reflection = New Bitmap(magicMap.Library(ReflectionIndex)).Cube
        Else
            'Reflection = Globals.defaultCube(IShader.DefaultTextures.SignedAdditive)
        End If

        If SpecularIndex > -1 Then
            Specular = New Bitmap(magicMap.Library(SpecularIndex)).Cube
        Else
            'Specular = Globals.defaultCube(IShader.DefaultTextures.Additive)
        End If
    End Sub
    Overloads Sub Dispose()

    End Sub
    Public Overloads Sub BeginPass(ByVal pass As Integer) Implements IShader.BeginPass
        If pass = 0 Then
            xDevice.SetRenderState(RenderState.AlphaTestEnable, (Flags And 1 <> 1))
            xDevice.SetRenderState(RenderState.AlphaRef, 255)
            xDevice.SetRenderState(RenderState.AlphaFunc, Compare.Less)
            xDevice.SetRenderState(RenderState.CullMode, IIf((Flags And 4 = 0), Cull.Counterclockwise, Cull.None))

            xDevice.SetRenderState(RenderState.AlphaBlendEnable, True)
            xDevice.SetRenderState(RenderState.SourceBlend, Blend.SourceColor)
            xDevice.SetRenderState(RenderState.DestinationBlend, Blend.BlendFactor)
            xDevice.SetRenderState(RenderState.BlendOperation, BlendOperation.Add)
            xDevice.SetRenderState(RenderState.BlendFactor, BackgroundColor.ToArgb)

        ElseIf pass = 1 Then
            xDevice.SetRenderState(RenderState.SourceBlend, Blend.SourceColor)
            xDevice.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceColor)

        End If

        sglaEffect.BeginPass(pass)
    End Sub
    Public Overloads Sub EndPass() Implements IShader.EndPass
        sglaEffect.EndPass()
    End Sub
    Public Overloads Function BeginShader(ByVal tLightmap As Texture) As Integer Implements IShader.BeginShader
        sglaEffect.SetValue("cameraPosition", New Vector4(Camera.Position.X, Camera.Position.Y, Camera.Position.Z, 1.0F))
        sglaEffect.SetValue("world", xDevice.GetTransform(TransformState.World))
        sglaEffect.SetValue("worldViewProjection", xDevice.GetTransform(TransformState.World) * xDevice.GetTransform(TransformState.View) * xDevice.GetTransform(TransformState.Projection))
        sglaEffect.SetValue("fogStart", xDevice.GetRenderState(RenderState.FogStart)) '0.0F) ' MdxRender.Device.RenderState.FogStart);
        sglaEffect.SetValue("fogEnd", xDevice.GetRenderState(RenderState.FogEnd)) ' MdxRender.Device.RenderState.FogEnd);
        sglaEffect.SetValue("fogDensity", xDevice.GetRenderState(RenderState.FogDensity)) ' MdxRender.Device.RenderState.FogDensity);

        sglaEffect.SetValue("parallelBrightness", ParallelBrightness)
        sglaEffect.SetValue("perpendicularBrightness", PerpendicularBrightness)
        sglaEffect.SetValue("parallelColor", ParallelColor)
        sglaEffect.SetValue("perpendicularColor", PerpendicularColor)
        sglaEffect.SetValue("backgroundTintColor", BackgroundColor)

        sglaEffect.SetValue("diffuseScale", DiffuseScale)
        sglaEffect.SetValue("bumpScale", BumpScale)
        sglaEffect.SetValue("tintScale", TintScale)
        sglaEffect.SetValue("detailScale", DetailScale)
        sglaEffect.SetValue("specularScale", SpecularScale)

        sglaEffect.SetTexture("DiffuseMap", Diffuse)
        sglaEffect.SetTexture("BumpMap", Bump)
        sglaEffect.SetTexture("DetailMap", Detail)
        sglaEffect.SetTexture("TintMap", Tint)
        sglaEffect.SetTexture("EnvironmentMap", Reflection)
        sglaEffect.SetTexture("SpecularMap", Specular)

        If ReflectionType = 1 Then
            If (Specular Is Nothing) Then
                sglaEffect.Technique = "FlatGlass"
            ElseIf (Diffuse Is Nothing AndAlso Reflection Is Nothing) Then
                sglaEffect.Technique = "FlatGlassSpecular"
            Else
                sglaEffect.Technique = "FlatGlassTwoPass"
            End If
        Else
            If Specular Is Nothing Then
                sglaEffect.Technique = "BumpedGlass"
            ElseIf (Diffuse Is Nothing AndAlso Reflection Is Nothing) Then
                sglaEffect.Technique = "BumpedGlassSpecular"
            Else
                sglaEffect.Technique = "BumpedGlassTwoPass"
            End If
        End If

        Return sglaEffect.Begin(FX.DoNotSaveState)
    End Function
    Public Overloads Sub EndShader() Implements IShader.EndShader
        sglaEffect.End()
    End Sub
End Class
